﻿<?php 
// PHP version
//echo 'PHP version '.PHP_VERSION;
// functions
include ('functions.php');
//
class smartic {
    // all elements only
    protected static $elements = array();
    // all elements by types
    protected static $elements_info = array();
    // options for the form
    // submit button
    static $submit = FALSE;
    // change methods(get or post)
    static $method = FALSE;
    // page submited or not
    static $submit_status = FALSE;
    // constructor function
    public function __construct($options_passed = false) {
        // to collect options
        $options = get_Options($options_passed);
        // to set the options for the form
        $this->setOption($options);
        // check if page submited or not
        if (self::$submit) {
            $method_up_case = strtoupper(self::$method);
            $method = (!in_array($method_up_case, array('POST', 'GET'))) ? 'POST' : $method_up_case;
            if (isset($GLOBALS['_'.$method][self::$submit])) {
                self::$submit_status = true;
            }
        } else if ($_POST || $_GET) {
            self::$submit_status = true;
        }
    }
    // when he call element dosn't exists
    public function __call($type, $argument = NULL) {
        // if the type supported
        if (!method_exists($this, $type) and file_exists('smartic/types/'.$type.'.php')) {
            // if we called it before
            if (!isset(self::$elements_info[$type])) {
                // for first time only
                include_once ('types/'.$type.'.php');
            }
            // add to elements type num
            (!isset(self::$elements_info[$type]['elements_num'])) ? self::$elements_info[$type]['elements_num'] = 1 : self::$elements_info[$type]['elements_num']++;
            // create array for elements
            if (!isset(self::$elements_info[$type]['elements'])) {
                self::$elements_info[$type]['elements'] = array();
            }
            // return the new element
            return new $type($argument);
        } else {
            $this->debug('error there is no method or type with this name ('.$type.')');
        }
    }
    // in the end
    public function __destruct() {
    
    }
    // to set new properties to the form
    private function setOption($options) {
        if (is_array($options)) {
            foreach ($options as $key=>$val) {
                // to set options for the form
                if (isset(self::$$key)) {
                    self::$$key = $val;
                } else {
                    self::debug('this option "'.$key.'" dosn\'t exists');
                }
            }
        }
    }
    // function to render html data
    public function render($element_name = FALSE) {
        // element data
        $element_data = $this->getElements($element_name);
        //
        if ($element_data) {
            // echo HTML
            if (isset($element_data['HTML'])) {
                echo htmlspecialchars_decode($element_data['HTML']);
            }
        } else {
            // debug message
            self::debug('there is no element with this name you have requested '.$element_name);
        }
    }
    // to render element errors
    public function showerror($element_name = FALSE) {
        // element data
        $element_data = $this->getElements($element_name);
        if ($element_data) {
            // if pge was submitted and tere isan errors
            if (isset($element_data['errors'])) {
                echo '<ul class="errorbox_'.$element_data['name'].'">';
                foreach ($element_data['errors'] as $key=>$val) {
                    echo '<li>'.$val.'</li>';
                }
                echo '</ul>';
            }
        } else {
            // debug message
            self::debug('there is no element with this name you have requested '.$element_name);
        }
    }
    // return element properties
    public function getElement($name = false) {
        if ($name and array_key_exists($name, self::$elements)) {
            return self::$elements[$name];
        }
        // could not find the element
        $this->debug('could not find this element "'.$name.'"');
    }
    // return all elements only
    public function getElements($child = false) {
        if ($child) {
            $elements = have_child(self::$elements, $child, true);
        } else {
            $elements = self::$elements;
        }
        return $elements;
    }
    // return elements info
    public function getElementInfo($child = false) {
        if ($child) {
            $elements_info = have_child(self::$elements_info, $child, true);
        } else {
            $elements_info = self::$elements_info;
        }
        return $elements_info;
    }
    // add new element
    protected function addNewElementToElements($element) {
        if (is_array($element)) {
            self::$elements_info[$element['type']]['elements'][$element['name']] = $element;
            return self::$elements[$element['name']] = $element;
        }
        // could not find the element
        $this->debug('wrong data type array "'.$element.'"');
    }
    // function to handel debuging errors
    protected function debug($msg = false) {
        if ($msg) {
            echo $msg.'.<br/>';
            exit;
        }
    }
    // function to handel validation errors
    protected function addError($errorMsg) {
        $NerrorMsg = $errorMsg;
        $sta_Id = '{{';
        $end_Id = '}}';
        if (strpos($errorMsg, $sta_Id) and strpos($errorMsg, $end_Id)) {
            // get attr from config errors and replace them with this elem attr
            preg_match_all('/'.$sta_Id.'[\w\.]+'.$end_Id.'/', $errorMsg, $match);
            $match_count = count($match[0]);
            if ($match_count) {
                for ($i = 0; $i < $match_count; $i++) {
                    // strip two {{ }}
                    $match_after_strip = strtr($match[0][$i], array($sta_Id=>"", $end_Id=>""));
                    // if this attribute exists for this element
                    if (isset($this->element[$match_after_strip]) or strpos($match_after_strip, '.')) {
                        $NerrorMsg = strtr($NerrorMsg, array($match[0][$i]=>have_child($this->element, $match_after_strip, true)));
                    }
                }
            }
        }
        // add number of errors for this element only
        if (!isset($this->element['errors_num'])) {
            $this->element['errors_num'] = 0;
        }
        $this->element['errors_num']++;
        $this->element['errors'][] = $NerrorMsg;
    }
}
?>
